package com.didang;

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.log4j.Logger;

import com.didang.exception.NoPkAnnotationException;
import com.didang.exception.PkValueIsNullException;

/**
 * sqlVO生成器
 * @author didang
 *
 */
public class SqlVOGenerator {
	
	private final static Logger log = Logger.getLogger(SqlVOGenerator.class);

	private Model model;
	
	public SqlVOGenerator(Model __model){
		this.model = __model;
	}
	
	/**
	 * 生成新增操作的sqlVO
	 * @return
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws NoSuchMethodException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchFieldException 
	 */
	public SqlVO generateInsertSqlVO() throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException{
		SqlVO sqlVO = new SqlVO();
		String placeholders = "";
		Vector params = null;
		String tableName = ModelHelper.getTableName(this.model.getClass());
		String insertSql = "insert into "+tableName+"(";
		Map map = ModelHelper.getColumnsAndValues(this.model);
		if(map != null){
			params = new Vector();
			Set keySet = map.keySet();
			for(Iterator iterator = keySet.iterator();iterator.hasNext();){
				Object column =  iterator.next();
				params.add(map.get(column));
				insertSql +=column+",";
				placeholders +="?,";
			}
			insertSql = insertSql.substring(0,insertSql.length()-1)+") values(";
			placeholders = placeholders.substring(0,placeholders.length()-1)+")";
			insertSql +=placeholders;
			log.info(insertSql);
			sqlVO.setSql(insertSql);
			sqlVO.setParams(params.toArray());
			return sqlVO;
		}
		return null;
	}
	
	/**
	 * 生成删除操作的sqlVO
	 * @return
	 * @throws NoPkAnnotationException
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws NoSuchMethodException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws PkValueIsNullException
	 * @throws NoSuchFieldException 
	 */
	public SqlVO generateDeleteSqlVO() throws NoPkAnnotationException, SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, PkValueIsNullException, NoSuchFieldException{
		SqlVO sqlVO = new SqlVO();
		Vector params = new Vector();
		String tableName = ModelHelper.getTableName(this.model.getClass());
		String deleteSql = "delete from "+tableName+" where ";
		SqlVO wheresVO = this.model.getWheresVO();
		if(wheresVO != null){
			deleteSql += wheresVO.getSql();
			for(Object param : wheresVO.getParams()){
				params.add(param);
			}
		}else{
			Map<?, ?> pkMap = ModelHelper.getPrimaryKeysAndValues(this.model);
			if(pkMap != null){
				Set<?> pkSet = pkMap.keySet();
				for(Iterator<?> iterator = pkSet.iterator();iterator.hasNext();){
					Object pk =  iterator.next();
					params.add(pkMap.get(pk));
					deleteSql +=pk+"=?,";
				}
				deleteSql = deleteSql.substring(0,deleteSql.length()-1);
			}else{
				throw new NoPkAnnotationException();
			}
		}
		log.info(deleteSql);
		sqlVO.setSql(deleteSql);
		sqlVO.setParams(params.toArray());
		return sqlVO;
	}
	
	
	/**
	 * 生成更新操作的sqlVO
	 * @return
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws NoSuchMethodException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchFieldException
	 * @throws NoPkAnnotationException 
	 * @throws PkValueIsNullException 
	 */
	public SqlVO generateUpdateSqlVO() throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, NoPkAnnotationException, PkValueIsNullException{
		SqlVO sqlVO = new SqlVO();
		Vector params = null;
		String tableName = ModelHelper.getTableName(this.model.getClass());
		String updateSql = "update "+tableName+" set ";
		Map map = ModelHelper.getNormalColumnsAndValues(this.model);
		if(map != null){
			params = new Vector();
			Set keySet = map.keySet();
			for(Iterator iterator = keySet.iterator();iterator.hasNext();){
				Object column =  iterator.next();
				params.add(map.get(column));
				updateSql +=column+"=?,";
			}
			updateSql = updateSql.substring(0,updateSql.length()-1);
			updateSql += " where ";
			
			SqlVO wheresVO = this.model.getWheresVO();
			if(wheresVO != null){
				updateSql += wheresVO.getSql();
				for(Object param : wheresVO.getParams()){
					params.add(param);
				}
			}else{
				Map<?, ?> pkMap = ModelHelper.getPrimaryKeysAndValues(this.model);
				if(pkMap != null){
					Set<?> pkSet = pkMap.keySet();
					for(Iterator<?> iterator = pkSet.iterator();iterator.hasNext();){
						Object pk =  iterator.next();
						params.add(pkMap.get(pk));
						updateSql +=pk+"=?,";
					}
					updateSql = updateSql.substring(0,updateSql.length()-1);
				}else{
					throw new NoPkAnnotationException();
				}
			}
			log.info(updateSql);
			sqlVO.setSql(updateSql);
			sqlVO.setParams(params.toArray());
			return sqlVO;
		}
		return null;
	}

}
